//
//  CaptureLogic.swift
//  SwiftuiUno
//
//  Created by baozi on 2023/11/27.
//

import Foundation
import AVFoundation
import SwiftUI
class CaptureLogic: NSObject, ObservableObject, AVCapturePhotoCaptureDelegate, AVCaptureMetadataOutputObjectsDelegate {
     var session = AVCaptureSession()
    
     var alert = false
    
     var output = AVCapturePhotoOutput()
    
     var preview : AVCaptureVideoPreviewLayer!
    
     var isSaved = false
    
     @Published var picDatas: [CaptureImageData] = []
    
    func Check(){
        DispatchQueue.global(qos: .background).async {
            switch AVCaptureDevice.authorizationStatus(for: .video) {
            case .authorized:
                self.setUp()
                return
            case .notDetermined:
                AVCaptureDevice.requestAccess(for: .video) { (status) in
                    if status{
                        self.setUp()
                    }
                }
            case .denied:
                self.alert.toggle()
                return
            default:
                return
            }
        }

    }
    
    
    
    func setUp(){
        do{
            let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: .video, position: .back)
            let devices = deviceDiscoverySession.devices
            let captureDevice = devices.first
            let input = try AVCaptureDeviceInput(device: captureDevice!)
            if self.session.canAddInput(input) {
                self.session.addInput(input)
            }
            
            if self.session.canAddOutput(self.output){
                self.session.addOutput(self.output)
            }
            // 将输入设备添加到捕获对象
            let metadataOutput = AVCaptureMetadataOutput()
            if (session.canAddOutput(metadataOutput)) {
                session.addOutput(metadataOutput)
                metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
                metadataOutput.metadataObjectTypes = [.qr]
            }
            // 启动捕获会话对象
            DispatchQueue.global().async {
                self.session.startRunning()
            }
        }catch{
            print(error.localizedDescription)
        }
    }
    
    func takePic(){
        DispatchQueue.global(qos: .background).async {
            let settings = AVCapturePhotoSettings()
            self.output.capturePhoto(with: settings, delegate: self)
        }
    }
    
    func reTake(){
        DispatchQueue.global(qos: .background).async {
            self.session.startRunning()
            DispatchQueue.main.async {
                self.isSaved = false
            }
        }
    }
    
    func cancelBack() {
        DispatchQueue.global(qos: .background).async {
            self.session.stopRunning()
        }
    }
    
    @MainActor func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
        if error != nil{
            return
        }
        if picDatas.count >= 4 {
            ToastManager.show(text: "最多只能四张图片")
            return
        }
        print("pic taken...")
        
        guard let imageData = photo.fileDataRepresentation() else {
            return
        }
        let imgData = CaptureImageData(datas: imageData)
        picDatas.append(imgData)
    }
    
    
    
    func savePic(){
//        let image = UIImage(data: self.picData)!
//        UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
//        
//        self.isSaved = true
//        print("Saved Successfully...")
    }
}

struct CameraPreview : UIViewRepresentable {
    @ObservedObject var camera : CaptureLogic
    func makeUIView(context: Context) -> UIView {
        let view = UIView(frame: UIScreen.main.bounds)
        camera.preview = AVCaptureVideoPreviewLayer(session: camera.session)
        camera.preview.frame = view.frame
        
        camera.preview.videoGravity = .resizeAspectFill
        
        view.layer.addSublayer(camera.preview)
        return view
        
    }
    
    func updateUIView(_ uiView: UIView, context: Context) {
        return
    }
}

struct CaptureImageData: Identifiable, Hashable {
    var id: UUID = UUID()
    var datas: Data = Data()
    
    static func == (lhs: Self, rhs: Self) -> Bool {
        return lhs.id == rhs.id
    }
    
}
